home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
ask
/
dictk
/
source
/
dictk.s
< prev
Wrap
Text File
|
1998-09-30
|
25KB
|
987 lines
*********************************************************************
* ASK3アクセサリ DicTK V3.1
* Copyright (C) 1996-98 by AIG-Soft
*********************************************************************
.include defines.mac
.include pspdef.mac
.include ask3.mac
.include gmd.mac
.xref _GMDSetAPI
.xref GMDCallAPI
*********************************************************************
* 常駐ルーチン
*********************************************************************
* 年号をわざわざテキストでなしにバイナリー化しているのは、テキストのみより
* 誤った一致をしにくいから
.text
.even
KEEP_START:
* 常駐確認用識別子
id: .dc.b 'DicTK V3.1',19,98,'AIG-Soft',0
*********************************************************************
* ワーク1
*********************************************************************
.even
ACh: .dc.l -1 * アクセサリアドレス(初期値-1<0)
first: .dc.w 0 * DicTouroku
ferr: .dc.w 0 * DicTouroku
NulPt: .dc.l 0 * NULデバイスのアドレス
AdGMDAPI: .dc.l 0 * GMDのAPIアドレス(0=GMDなし)
hinname: * 品詞名アドレス群
.dc.l Hin01,Hin02,Hin03,Hin04,Hin05,Hin06,Hin07,Hin08,Hin09,Hin10
.dc.l Hin11,Hin12,Hin13,Hin14,Hin15,Hin16,Hin17,Hin18,Hin19,Hin20
.dc.l Hin21,Hin22,Hin23,Hin24,Hin25,Hin26,Hin27,Hin28,Hin29,Hin30
MEISI equ 17 * 名詞の品詞番号
HINMAX equ 30 * 品詞種類数
TErrMes: * エラーメッセージアドレス表
.dc.l ErrDicShu,ErrHinshi,ErrYomi,ErrTouroku,ErrDicOpen,ErrASKExec
* 登録系エラーメッセージ
ErrDicShu: .dc.b '辞書種類がおかしい',0
ErrHinshi: .dc.b '品詞がおかしい',0
ErrYomi: .dc.b '読みがおかしい',0
ErrTouroku: .dc.b '登録できない',0
ErrDicOpen: .dc.b '辞書がオープン出来ない',0
ErrASKExec: .dc.b 'ASKが起動出来ない',0
* その他エラーメッセージ
ErrYomi2Long: .dc.b '読みが長すぎる',0
* メッセージ
JNAME: .dc.b '辞書登録',0
YNAME: .dc.b '読み=',0
TNAME: .dc.b '単語=',0
HNAME: .dc.b '品詞=',0
TLEN equ 6 * "単語="の長さ
LMAX equ 39*2-TLEN * 入力最大長
* 品詞名群(V3では4文字以内に統一)
Hin01: .dc.b 'カ行五段',0
Hin02: .dc.b 'ガ行五段',0
Hin03: .dc.b 'サ行五段',0
Hin04: .dc.b 'タ行五段',0
Hin05: .dc.b 'ナ行五段',0
Hin06: .dc.b 'バ行五段',0
Hin07: .dc.b 'マ行五段',0
Hin08: .dc.b 'ラ行五段',0
Hin09: .dc.b 'ワ行五段',0
Hin10: .dc.b 'サ変変格',0
Hin11: .dc.b 'カ変変格',0
Hin12: .dc.b '上下一段',0
Hin13: .dc.b '形容詞',0
Hin14: .dc.b '形容動詞',0
Hin15: .dc.b '形動名詞',0
Hin16: .dc.b 'サ変名詞',0
Hin17: .dc.b '名詞',0
Hin18: .dc.b '単漢字',0
Hin19: .dc.b '人名(姓)',0
Hin20: .dc.b '人名(名)',0
Hin21: .dc.b '地名',0
Hin22: .dc.b '団体名',0
Hin23: .dc.b '物の名称',0
Hin24: .dc.b '数詞',0
Hin25: .dc.b '数字',0
Hin26: .dc.b '接尾語',0
Hin27: .dc.b '感動詞',0
Hin28: .dc.b '接続詞',0
Hin29: .dc.b '副詞',0
Hin30: .dc.b '連体詞',0
.even
*********************************************************************
* 本来外部にあるべきルーチン
*********************************************************************
* 本来外部にあるべきルーチン
* DicTK内部はスーパーバイザーで走るから、これで良い。
GMDAPI0 macro no
moveq.l #no,d0 * コマンドセット
bsr GMDCallAPI0 * GMD API呼びだし
endm
GMDCallAPI0: * API呼びだし
* d0.b=コマンド
move.l AdGMDAPI(pc),-(sp)
rts * 飛び先からrtsする
*********************************************************************
BREAKOFF macro
move.w #-1,-(sp) * read BREAK mode
DOS _BREAKCK
move.w d0,brksts
clr.w -(sp) * BREAK Cut
DOS _BREAKCK
addq.w #2*2,sp
endm
BREAKON macro
move.w brksts(pc),-(sp)
DOS _BREAKCK * BREAK on
addq.w #2,sp
endm
DicTouroku:
* 辞書登録アクセサリ
* 1文字入力される毎にここに来る
move.w 4+2(sp),d0 * code
* movem.l d3-d7/a3-a6,-(sp)
move.w d0,d7 * d7=code(キーコード)
BREAKOFF * d0破壊
move.w #CACI_NORMAL,d3 * 規定外キー入力は無視するため(など)
moveq.l #0,d4 * 文字列を反転しない(msmode=0)
sub.l a3,a3 * mes=NULL(a3=0):メッセージ出力無し
* メインルーチン
move.w first(pc),d0
add.w d0,d0 * for .w
move.w FirstJTBL(pc,d0.w),d0
jsr FirstJTBL(pc,d0.w) * first毎の処理(0/1/2/3)
* ret=d3.l , msmode=d4.l
* メッセージがあったら表示(a3)
cmp.l #0,a3 * mes=NULL?
beq 1f * Yes
* メッセージがある
cmp.l #2,d4 * msmode=2?
bne @f
BEEP * エラー(d0,d1破壊)
moveq.l #1,d4 * msmode=1(反転表示)
@@: * kbuf[Str2MEAN(mes,kbuf,msmode)]=0
move.l a3,a0 * mes
move.l #kbuf,d0
move.l d4,d1 * msmode
bsr Str2MEANS
or.w #DF_KWINSTR,d3 * kstrを表示させるため
1: BREAKON * d0破壊
move.w d3,d0 * return(ret)
* movem.l (sp)+,d3-d7/a3-a6
rts
FirstJTBL:
* first順
.dc.w PrintYomi-FirstJTBL // 0
.dc.w TangoJunbi-FirstJTBL // 1
.dc.w TagoShitei-FirstJTBL // 2
.dc.w HinshiSelect-FirstJTBL // 3
*------------------------------------
Str2MEANS:
* buf[Str2MEAN(mes,buf,mode)]=0
* a0 <- mes
* d0.l <- buf
* d1.l <- mode (0=通常表示,1=反転表示)
move.l d1,-(sp) * mode
move.l d0,-(sp) * buf
pea (a0) * mes
pea 62.w
DOS _KNJCTRL
lea 4*4(sp),sp
move.l -8(sp),a0 * buf
add.w d0,d0 * .w=MEAN
clr.w (a0,d0.w) * buf[..]=0
rts
*------------------------------------
SearchKeyJ:
* d7.w <- code
* a0 <- jump table
* 少なくともd0/d1/a0破壊
move.w d7,d1
and.w #NAKEY,d1
@@: move.l (a0)+,d0 * jump|code
beq @f * -> end of table
cmp.w d1,d0 * =code?
bne @b * no
swap d0 * d0=jump
jmp -4(a0,d0.w) * 飛び先からrtsする
*
@@: rts * default
*------------------------------------
PrintYomi:
* 読みの表示(first=0)
tst.w ferr
beq @f
clr.w ferr
move.w #CACI_END,d3
rts * 元に戻る(変換ライン仮入力)
*
@@: * このときcbufに入っているのが読みとなる
lea cbuf(pc),a3 * mes=cbuf
move.l a3,a0
moveq.l #-1,d0
@@: addq.w #1,d0 * strlen(cbuf)
tst.b (a0)+
bne @b
cmp.w #LMAX,d0 * len>LMAX?
bls @f
* 読みが長すぎる
lea ErrYomi2Long(pc),a3 * mes=エラーメッセージ
moveq.l #2,d4 * msmode=2
move.w #1,ferr * ferr=1
rts
*
@@: * 読みの長さはok
move.l a3,a0 * mes=cbuf
lea yomi(pc),a1
@@: move.b (a0)+,(a1)+ * yomi<-mes
bne @b
*
lea YNAME(pc),a0 * "読み="
lea yomi(pc),a2 * 読みそのもの
bsr StrCpyCat * mes<-YNAME+yomi
*
lea JNAME(pc),a0 * 辞書登録
move.l #mbuf,d0
moveq.l #1,d1 * 反転表示
bsr Str2MEANS
move.w #CACI_NORMAL|DF_MWINSTR,d3
move.w #1,first * 次のキー入力からが実際の単語登録になる
rts
*------------------------------------
TangoJunbi:
* "単語="(TNAME)の表示と取り込み準備(first=1)
* 現在は読みが表示されている
* この段階で終了キーが押されたら終わってしまう
and.w #NAKEY,d7
cmp.w #NOT_ASCII|TOUROKU_KEY,d7
beq 1f * CTRL+登録のキーリピートですぐ終わらないように
cmp.w #ESC,d7
bne @f
* 単語指定中->終了
clr.w first
move.w #CACI_END,d3
1: rts
*
@@: * 単語指定モード
move.l CSRX.w,xy0 * 現在のカーソル位置を保存(x,y)
move.w #2,first * first=2
moveq.l #0,d0
move.l d0,pt * pt=pt2=0
move.w d0,ferr * ferr=0
lea tango(pc),a3 * mes=tango
move.l a3,a0
lea TNAME(pc),a1
@@: move.b (a1)+,(a0)+ * tango<-TNAME
bne @b
* GMD設定(これは使用直前に設定する)
lea Writer(pc),a2
GMDAPI0 GMD_SetWriter * Writer設定
move.l d0,Wt
lea Group(pc),a2
GMDAPI0 GMD_SetGroup * Group設定
move.l d0,Gp
move.w #CACI_URGENT,d3 * TNAMEを表示してすぐに戻ってくる
rts
*------------------------------------
TagoShitei:
* 単語指定モード(first=2)
move.l CSRXMAX.w,d5 * テキスト画面の幅:xm|ym
swap d5
move.l CSRX.w,d6 * カーソル位置 : x|y
swap d6 * xの方がよく処理されるのでxをlowに置く
lea TJTable(pc),a0
bsr SearchKeyJ * キーに相当した処理へのジャンプ
* <- ここに戻ってくる
* カーソル移動
swap d6 * y|x -> x|y
bmi @f * d6.l=-1のときはカーソルはすでに移動されているので処理しない
cmp.l CSRX.w,d6
beq @f * 移動はない
* カーソルoffは移動時の瞬間だけにしてカーソルが見えなくなるのを最小限にする
IOCS _B_CUROFF * カーソルを操作するため
move.l d6,CSRX.w
IOCS _B_CURON * カーソル戻し
@@: rts
TJTable:
* jump先(offset),code
.dc.w LT_CLR-$,NOT_ASCII|CLR_KEY
.dc.w LT_BS-$,BS
.dc.w LT_SPC-$,SPC
.dc.w LT_CR-$,CR
.dc.w LT_TOUROKU-$,NOT_ASCII|TOUROKU_KEY
.dc.w LT_ESC-$,ESC
.dc.w LT_UNDO-$,NOT_ASCII|UNDO_KEY
* 以下はカーソル移動キー
.dc.w LT_LEFT-$,NOT_ASCII|LEFT_KEY
.dc.w LT_UP-$,NOT_ASCII|UP_KEY
.dc.w LT_RIGHT-$,NOT_ASCII|RIGHT_KEY
.dc.w LT_DOWN-$,NOT_ASCII|DOWN_KEY
.dc.w LT_DEL-$,NOT_ASCII|DEL_KEY
.dc.w LT_HOME-$,NOT_ASCII|HOME_KEY
.dc.w 0,0 * end of table
LT_CR: * 単語決定
tst.w pt
bne @f
* まだ1文字も指定されていない
BEEP * d0,d1破壊
rts
*
@@: move.w #MEISI,fhinshi * 次は品詞選択(名詞から)
move.w #3,first * first=3
bra HINEND
LT_TOUROKU: * 登録
DEND: btst.l #B_CTRL_ON,d7
bne 8f * CTRL+登録で中断
LT_ESC: * 単語指定中->終了
DEND2: * GMDを戻す(これは毎回必要)
move.l Wt(pc),d0
GMDAPI0 GMD_SetWriter * Writer戻し
move.l Gp(pc),d0
GMDAPI0 GMD_SetGroup * Group戻し
clr.w first * 読みの表示に戻る
move.w #CACI_END,d3 * 終了
LT_UNDO: * カーソルを元の位置に戻す
move.l xy0(pc),d6 * x|y
swap d6 * y|x(他に合わせるため)
8: rts
LT_BS: * 読み込み中文字1文字削除
move.w pt(pc),d0
beq 8b * pt=0:何も入っていないときは何もしない
* pt>0
subq.w #1,d0 * pt--
move.w d0,pt
add.w d0,d0 * for word
moveq.l #1,d1 * pt2-1
lea wtango(pc),a0
add.w d0,a0
cmp.w #$ff,(a0) * wtango[pt]>$ff?
bls @f * <=
moveq.l #2,d1 * pt2-2
@@: sub.w d1,pt2
clr.w (a0) * wtango[pt]=0
bra ENT
LT_CLR: * 読み込み中文字全削除
tst.w pt
beq 7f * pt=0:何も入っていないときは何もしない
clr.l pt * pt=pt2=0
clr.w wtango * wtango[0]=0
bra ENT
*
LT_SPC: * 1文字取得
moveq.l #-1,d6 * カーソルはすでに移動されているの印
btst.l #B_CTRL_ON,d7
beq @f * SPCで1文字読みとり
* CTRL+SPC:単語一気読みとり
moveq.l #-1,d1 * 現在カーソル位置から
GMDAPI0 GMD_ReadTango * カーソルも移動する
tst.l d0
beq 7f * -> rts 1文字も読み込めていない
bra ENT
*
@@: * SPC:1文字読み込み
move.w #$a0,d1 * SHIFT+SPACE = $a0スペースのため
btst.l #B_SHIFT_ON,d7
bne @f * -> SHIFT+SPACE
* 1文字読み込み
moveq.l #-1,d1 * 現在カーソル位置から
GMDAPI0 GMD_Read1 * -> d0.l
move.l d0,d1 * 保存
swap d1 * d1.w=幅
GMDAPI0 GMD_MoveCursor * カーソル移動
swap d1 * d1.w=文字
cmp.w #NOCHR,d1
beq 7f * 読み込めていない(rts)
cmp.w #' ',d1 * スペース?
beq 7f * Yes -> スペースは書き込まない
@@: move.w d1,d0
bsr Writer0 * 書き込み
tst.l d0
bne 7f * error -> ret
ENT: * 入力した文字を表示
lea tango(pc),a3 * mes=tango
lea TLEN(a3),a0 * TLENの後ろに単語をつける
lea wtango(pc),a1 * t=wtango
bra.s 6f
*
5: cmp.w #$ff,d1 * <=$ff?
bls @f * Yes
* 2バイトコード
move.w d1,d0
lsr.w #8,d0
move.b d0,(a0)+ * 2バイトコードの上位バイト
@@: move.b d1,(a0)+
6: move.w (a1)+,d1 * c=*t++
bne 5b
clr.b (a0) * EOS
7: rts
* カーソル移動
* d6.l = CSRY|CSRX
* d5.l = CSRYMAX|CSRXMAX
LT_HOME:
moveq.l #0,d6 * x=y=0
rts
LT_DEL:
move.l d5,d6 * x=xm,y=ym
rts
LT_LEFT:
btst.l #B_CTRL_ON,d7
beq @f * LEFTのみ
* CTRL+LEFT : 左端
clr.w d6 * x=0
1: rts
*
@@: subq.w #1,d6 * x--
bge 1b * >=0 -> ret
move.w d5,d6 * 画面左端x=0->右端x=xm & y-1
LT_UP:
swap d6 * y
subq.w #1,d6 * y--
bge @f * >=0 -> ret
swap d5 * ym
move.w d5,d6 * 画面最上y=0->最下y=ym
* swap d5
@@: swap d6
rts
LT_RIGHT:
btst.l #B_CTRL_ON,d7
beq @f * CTRLなし
* CTRL-RIGHT : 右端
move.w d5,d6 * x=xm
rts
*
@@ btst.l #B_SHIFT_ON,d7
beq @f * SHIFTなし
* SHIFT+RIGHT=TAB相当
and.w #$fff8,d6 * $fff8=(d6.w/8)*8
addq.w #8,d6
@@: * RIGHTのみ
addq.w #1,d6 * x++
cmp.w d5,d6 * x<=xm?
bls 1b * yes -> ret
clr.w d6 * 画面右端x=xm->左端x=0 & y+1
LT_DOWN:
swap d6 * y
swap d5 * ym
addq.w #1,d6 * y++
cmp.w d5,d6 * y<=ym?
bls @f * yes -> ret
clr.w d6 * 画面最下y=ym->最上y=0
@@: swap d6
* swap d5
rts
*------------------------------------
HinshiSelect:
* 品詞選択モード(first=3)
tst.w ferr
beq @f
* さっきエラーが出ている
clr.w ferr * エラーメッセージを消す
bra.s HINEND * 品詞表示
*
@@: move.w fhinshi(pc),d5 * fh=fhinshi
lea HJTable(pc),a0
bsr SearchKeyJ * キーに相当した処理へのジャンプ
* <- ここに戻ってくる
cmp.w fhinshi,d5 * 品詞は変わった?
beq 2f * No -> break
move.w d5,fhinshi * 変わった品詞を保存
HINEND: * "品詞情報="を表示(d5/d6は破壊しないように)
move.w fhinshi(pc),d0
subq.w #1,d0 * fhinshi-1
add.w d0,d0
add.w d0,d0 * for .l
lea hinname(pc),a2
move.l (a2,d0.w),a2 * a2=hinname[fhinshi-1]
lea HNAME(pc),a0
moveq.l #1,d4 * msmode=1(反転表示)
lea cbuf(pc),a3 * mes=cbuf
StrCpyCat:
* ここはサブルーチンでもある
* mes <- (a0)+(a2)
* a3 <- mes : 保存
* a0 <- ?NAME(文字列) : 破壊
* a2 <- str : 破壊
move.l a3,a1 * mes(cbuf)
@@: move.b (a0)+,(a1)+ * mes<-NAME
bne @b
subq.w #1,a1 * EOSを消す
@@: move.b (a2)+,(a1)+ * mes<<-str
bne @b
2: rts
*
HJTable:
* jump先(offset),code
.dc.w LH_UP-$,NOT_ASCII|UP_KEY
.dc.w LH_DOWN-$,NOT_ASCII|DOWN_KEY
.dc.w LH_HOME-$,NOT_ASCII|HOME_KEY
.dc.w LH_ESC-$,ESC
.dc.w DEND-$,NOT_ASCII|TOUROKU_KEY
.dc.w LH_CR-$,CR
.dc.w 0,0 * end of table
*
* d5.w=fhinshi
LH_UP: * UP
subq.w #1,d5 * fhinshi--
bgt @f * fhinshi>0
moveq.l #HINMAX,d5
@@: rts
LH_DOWN: * DOWN
addq.w #1,d5 * fhinshi++
cmp.w #HINMAX,d5 * fhinshi<=HINMAX?
bls @f
moveq.l #1,d5
@@: rts
LH_HOME: * HOME
moveq.l #MEISI,d5 * fhinshi=MEISI
rts
LH_ESC: * ESC : 品詞選択中->単語指定
move.w #2,first * 単語指定へ戻る
lea tango(pc),a3 * mes=tango
rts
DicTourokuSub macro
* 辞書登録
* d5(fhinshi)は破壊される
local L1,L2
* 準備
move.w d5,a5 * .w -> .l & 品詞保存
pea 2.w * 現在の変換モードを記録
DOS _KNJCTRL
move.l d0,d5 * -> d5
pea 0.w * off
pea 1.w * ASK終了(起動状態では単語登録出来ないから)
DOS _KNJCTRL
pea 8.w * 仮名漢字変換モード取得
DOS _KNJCTRL
move.l d0,d4 * -> d4
pea 0.w
pea 7.w * 仮名漢字変換モードのロック
DOS _KNJCTRL
pea 28.w * 辞書オープン
DOS _KNJCTRL
lea 4*7(sp),sp
moveq.l #5,d7 * 辞書がオープン出来ない時のためreturn(5)
tst.l d0
bne L1 * error
* 辞書はオープン出来た
pea (a5) * 品詞
pea tango+TLEN(pc) * 単語
pea yomi(pc) * 読み
pea 0.w
pea 30.w * 辞書登録
DOS _KNJCTRL
move.l d0,d7 * ferr=0~4
pea 29.w * 辞書クローズ
DOS _KNJCTRL
lea 4*6(sp),sp
L1: * 後処理
move.l d4,-(sp)
pea 7.w * 仮名漢字変換モードのアンロック
DOS _KNJCTRL
move.l d5,-(sp) * ASK再起動
pea 1.w
DOS _KNJCTRL
lea 4*4(sp),sp
tst.l d0
beq L2
moveq.l #6,d7 * return(6)
L2: *
endm
LH_CR: * 品詞決定->登録
DicTourokuSub * 辞書登録(d5.w=品詞) -> d7.w(ferr)
move.w fhinshi,d5 * 品詞は変わっていないの印
move.w d7,ferr
beq DEND2
* エラー(その後何かキーが押されるまで表示)
subq.w #1,d7 * ferr-1
add.w d7,d7
add.w d7,d7 * for longword
lea TErrMes(pc),a3
move.l (a3,d7.w),a3 * mes=TErrMes[ferr-1]
moveq.l #2,d4 * msmode=2
rts
*********************************************************************
GroupTBL:
* 単語として読みとる文字コードグループ
* no, end,start(大ざっぱでよい)
.dc.w 1,$ec9e,$889f * 全角:漢字(外字を含む)
.dc.w 2,$829a,$824f * 全角:英数
.dc.w 3,$8396,$829f * 全角:カナ
.dc.w 4,$81fc,$8141 * 全角:記号
.dc.w 4,$84fc,$839f * 全角:ギリシャ文字など
.dc.w 5,$007e,$0021 * 半角:かな以外
.dc.w 6,$00df,$00a1 * 半角:かな
.dc.w 6,$80df,$80a1 * 1/2:平仮名
.dc.w 7,$f1df,$f021 * 1/4:上付き
.dc.w 8,$f3df,$f221 * 1/4:下付き
.dc.w 0 * end of table(どこにも属さないときはグループ0)
* よく出てくる順に置くこと
.even
Group:
* 文字コードの属するグループを得る
* 4(sp) <- h.w=文字幅(1/2) , l.w=code
* -> d0.w : グループ番号 (h.wは不定)
move.w 4+2(sp),d2 * 文字コード
lea GroupTBL(pc),a0
@@: move.w (a0)+,d0 * グループ番号
beq @f * end
move.l (a0)+,d1 * h.w=end , l.w=start
cmp.w d1,d2 * c>=start?
bcs @b * no
swap d1
cmp.w d1,d2 * c<=end?
bhi @b * no
@@:
rts
*********************************************************************
Writer:
* 1文字書き込みルーチン
* おもにGMDから呼び出される
move.w 4+2(sp),d0 * cc=文字コード
Writer0:
move.l pt(pc),d1 * pt|pt2
addq.w #1,d1 * +sz(=1)
cmp.w #$ff,d0 * cc>$ff?
bls @f * no
addq.w #1,d1 * Yes : 2byte code
@@: * d1=pt2+sz
cmp.w #LMAX,d1 * >=LMAX?
bcs @f * no
* Yes : これ以上は書き込めない
BEEP * d0,d1破壊
moveq.l #1,d0 * return(1)
rts
@@: move.w d1,pt2 * pt2+=sz
lea wtango(pc),a0
swap d1 * pt
add.w d1,d1 * for .w
add.w d1,a0
move.w d0,(a0)+ * wtango[pt++]=cc
clr.w (a0) * wtango[pt]=0
addq.w #1,pt * pt++
moveq.l #0,d0 * return(0)
rts
*********************************************************************
* ワーク2
*********************************************************************
* ここに置くワークは、常駐後に使われるもの
* これらのワークエリアは常駐後に利用可能になるので、
* 以下の非常駐ルーチンからは参照しないこと
* 常駐後に非常駐部分をワークエリアにする定義
wordsz equ 2 * .wのサイズ
longsz equ 4 * .lのサイズ
*
mbufsz equ M_SIZE*wordsz * .ds.w M_SIZE
kbufsz equ K_SIZE*wordsz * .ds.w K_SIZE
cbufsz equ C_SIZE * .ds.b C_SIZE
wtangosz equ (LMAX+1)*wordsz * .ds.w LMAX+1
* 以上、確実に偶数サイズ
tangosz equ LMAX+TLEN+1+1 * .ds.b +1 for EOS/最後の+1は偶数バイトにするため
yomisz equ LMAX+1+1 * .ds.b (LMAX/TLENは共に偶数だから)
*
* ワークエリアアドレス
pt: * wtango[pt] : ptとpt2はこの順で並べること
pt2 equ pt+wordsz * tango[pt2]
brksts equ pt2+wordsz * BREAKCKモード
fhinshi equ brksts+wordsz * 品詞
xy0 equ fhinshi+wordsz * 最初のカーソル位置
Wt equ xy0+longsz * GMD 元Writer
Gp equ Wt+longsz * GMD 元Group
*
mbuf equ Gp+longsz * ASKモード表示
kbuf equ mbuf+mbufsz * ASK入力ライン->ASK
cbuf equ kbuf+kbufsz * ASK入力ライン<-ASK
wtango: equ cbuf+cbufsz * 単語(.w単位)
*
tango: equ wtango+wtangosz * 単語(.b単位)
yomi: equ tango+tangosz * 読み
* 常駐部分最後
KEEP_END equ yomi+yomisz
*********************************************************************
* 非常駐ルーチン
*********************************************************************
* アクセサリ定義構造体
*********************************************************************
.even
ACdef:
.dc.w KS_EDITING * 仮入力有り状態のみ
.dc.w CTRL_ON|NOT_ASCII|TOUROKU_KEY * CTRL+登録
.dc.l DicTouroku
.dc.l cbuf
.dc.l kbuf
.dc.l mbuf
*********************************************************************
* アクセサリ 組み込み/解除/初期化
*********************************************************************
DeleteAcc:
* a2 <- ACh
* -> Z : =0(ne):error , 1(eq)=ok
pea MesDicTK(pc)
DOS _PRINT
move.l (a2),-(sp) * ACh
pea 61.w
DOS _KNJCTRL
lea 4*3(sp),sp
move.l #MesDeleteOk,d2 * ok message
move.l d0,d1
beq @f * ret=0:Ok
* error
move.l #ErrCantDelete,d2 * error message
@@: move.l d2,-(sp)
DOS _PRINT
addq.w #4,sp
move.l d1,d0 * return
rts
*********************************************************************
AttachAcc:
* アクセサリの登録
* -> Z : 0(ne)=error , 1(eq)=ok
* ASKのバージョンチェック
pea 50.w
DOS _KNJCTRL
addq.w #4,sp
cmp.l #300,d0 * <300? (V3.00未満?)
bcc @f * No (V3.00以降)
* ASK V3.00以降でない
moveq.l #3,d1 * return(3)
pea ErrASK3(pc)
bra 1f
*
@@: * アクセサリの登録
pea MesDicTK(pc)
DOS _PRINT
pea ACdef(pc)
pea 60.w
DOS _KNJCTRL
lea 4*3(sp),sp
cmp.l #-1,d0 * error?
bne @f * no
* アクセサリに登録出来ない
moveq.l #4,d1 * return(4)
pea ErrCantAttach(pc)
bra 1f
*
@@: move.l d0,ACh * ACh=ret;
moveq.l #0,d1 * return(0)
pea MesAttachOk(pc)
1: DOS _PRINT
addq.w #4,sp
move.l d1,d0 * ret
rts
******************************************************************************
* この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
.even
chkarg: * コマンドライン解析(a2=コマンドライン)
tst.b (a2)+ * コマンドラインサイズ = 0?
beq eos * Yes : 引数がない
arglp: bsr skipsp * 空白飛ばし
tst.b d0 * end?
beq eos * Yes
* オプションは -? or /?
cmp.b #'-',d0
beq chkopt
cmp.b #'/',d0
bne arglp
chkopt: * オプションチェック
addq.w #1,a2 * skip '-' or '/'
move.b (a2)+,d0
beq usage * -/のみでオプションがない
or.b #$20,d0 * 小文字化
lea flags-2(pc),a6 * 後で+2するため-2しておく
@@: addq.w #2,a6
tst.b 1(a6)
beq usage * 全オプションチェック終わり -> 規定外オプション
tst.b (a6) * すでにフラグがセットされている?
bne @b * Yes : 飛ばす(2重指定だからbne usageにしてもいい)
cmp.b 1(a6),d0 * オプションチェック
bne @b * 不一致
st.b (a6) * セット
bra arglp * コマンドライン処理へ戻る
skipsp: * 空白飛ばし
move.b (a2)+,d0
cmp.b #' ',d0
beq skipsp
cmp.b #$09,d0 * TAB
beq skipsp
subq.w #1,a2 * a2が1つ進んでいるので戻す
eos: rts
*********************************************************************
* メイン
*********************************************************************
.xref keepchk
main:
lea.l initsp(pc),sp * PROGRAM=の時のため
pea title(pc) * タイトル表示
DOS _PRINT
*
move.l #(id-KEEP_START),-(sp) * 識別子の相対位置
pea.l (a0) * 自分のメモリ管理ポインタ
bsr keepchk * 常駐チェック
lea 4*3(sp),sp
move.b d0,d7 * d7 :0=常駐してない , -1=常駐している
* GMD API設定&アドレス保存
* 常駐/解除どちらでも使うから
movem.l a0/a2,-(sp)
jsr _GMDSetAPI
movem.l (sp)+,a0/a2
tst.l d0
beq Err_NoGMD * GMDがない
move.l d0,AdGMDAPI
*
bsr chkarg * コマンドライン引数チェック
tst.b rflag * -r : 常駐解除?
beq keep * no
*
* 常駐解除
*
tst.b d7 * 常駐している?
beq Err_NoKp * No -> error
* a0=常駐しているルーチンのメモリ管理ポインタ
* メモリー管理ポインタを飛ばし、ユーザープログラム先頭へ
* さらに、AChまで飛ばす
lea.l ACh-KEEP_START+PSPSIZ(a0),a2 * AChのアドレス
bsr DeleteAcc * アクセサリ解除
bne Err_Kai * アクセサリ登録削除不可により常駐解除不可
pea.l MPSIZ(a0)
DOS _MFREE * 自己プロセスメモリー解放
addq.w #4,sp
tst.l d0
bmi Err_Kai * なぜかメモリー解放出来ない時
* GMDを常駐アンロックする
GMDAPI GMD_JUnlock
* 常駐解除正常終了
pea.l MesRelease(pc)
DOS _PRINT
addq.w #4,sp
clr.w -(sp) * exit(0)
DOS _EXIT2
keep: * 常駐
tst.b d7 * 常駐している?
bne Err_Dbl * Yes -> error(2重常駐)
bsr AttachAcc * アクセサリ組み込み
bne Err_Keep * 組み込みエラー
*
* アクセサリも組み込みOK
* GMDを常駐ロックする
GMDAPI GMD_JLock
*
pea MesKeep(pc)
DOS _PRINT
clr.w -(sp) * exit(0)相当
pea (KEEP_END-KEEP_START).w
DOS _KEEPPR
*
* エラー終了
*
Err_NoGMD: * GMDがない
lea.l ErrNoGMD(pc),a0
bra.s error
Err_NoKp: * 常駐していないのに解除しようとした
lea.l NoKeep(pc),a0
bra.s error
Err_Dbl: * 2重常駐
lea.l AlreadyKeep(pc),a0
bra.s error
Err_Keep: * 常駐できない
lea.l CantKeep(pc),a0
bra.s error
Err_Kai: * 常駐解除不可
lea.l CantRelease(pc),a0
bra.s error
usage: * 使用法
lea.l MesUsage(pc),a0
error: move.w #2,-(sp) * STDERR
pea.l (a0)
DOS _FPUTS * 標準出力へ
addq.w #2+4,sp
move.w #2,-(sp) * exit(2)
DOS _EXIT2
******************************************************************************
* メッセージなど
******************************************************************************
.even
MesDicTK: .dc.b 'アクセサリ「リアルタイム単語登録」',0
MesDeleteOk: .dc.b 'を削除しました',$0d,$0a,0
ErrCantDelete: .dc.b 'が削除できません',$0d,$0a,0
ErrCantAttach: .dc.b 'が登録できません',$0d,$0a,0
MesAttachOk: .dc.b 'を登録しました',$0d,$0a,0
ErrASK3: .dc.b 'ASKがバージョン3以上ではありません',$0d,$0a,0
ErrNoGMD .dc.b 'GMDが組み込まれていません',$0d,$0a,0
title: .dc.b 'ASK3アクセサリ DicTK V3.1',$0d,$0a
.dc.b $09,'Copyright 1996-98 by AIG-Soft' * CrLfにつながる
CrLf .dc.b $0d,$0a,0
MesKeep: .dc.b '常駐しました',$0d,$0a,0
MesRelease: .dc.b '常駐解除しました',$0d,$0a,0
NoKeep: .dc.b '常駐していません',$0d,$0a,0
AlreadyKeep: .dc.b 'すでに常駐しています',$0d,$0a,0
CantKeep: .dc.b '常駐できません',$0d,$0a,0
CantRelease: .dc.b '常駐解除できません',$0d,$0a,0
MesUsage: .dc.b 'DicTK [/R]',$0d,$0a,0
.even
flags: * work,フラグキャラクター
rflag .dc.b 0,'r' * 常駐解除フラグ
.dc.b 0,0 * end of table
******************************************************************************
* 非常駐ルーチンが使うスタック
******************************************************************************
.stack
.even
.ds.l 512
initsp:
******************************************************************************
.end main